// 1. 导入依赖 + 手动定义 __dirname（ES 模块必需）
import { fileURLToPath } from 'url'
import path from 'path'
import simpleGit from 'simple-git'
import { promises as fs, existsSync } from 'fs'
// import { injectQiankun } from "./inject-qiankun.js";

// 手动定义 __dirname（获取当前脚本所在目录：scripts/）
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// 网络优化配置（可根据需要调整）
const httpBuffer = 524288000 // 500MB 大文件支持
const timeout = 300000 // 5分钟超时

// 2. 读取配置文件（scripts/repo.config.js）
async function readConfig() {
  const configPath = path.resolve(__dirname, 'repo.config.js')

  if (!existsSync(configPath)) {
    console.error('❌ 错误：未找到 repo.config.js，请在 scripts 目录下创建配置文件')
    process.exit(1)
  }

  try {
    const configModule = await import(configPath)
    const config = configModule.default || configModule

    if (!Array.isArray(config)) {
      throw new Error('配置文件必须导出一个数组')
    }
    config.forEach((item, index) => {
      if (!item.url || !item.dir) {
        throw new Error(`第 ${index + 1} 个仓库缺少 url 或 dir 配置`)
      }
    })

    return config
  } catch (err) {
    console.error(`❌ 配置文件错误：${err.message}`)
    process.exit(1)
  }
}

// 3. 检查 Git 是否安装
async function checkGitInstalled() {
  try {
    const git = simpleGit()
    await git.version()
  } catch {
    console.error('❌ 错误：未检测到 Git 环境，请先安装 Git 并配置到系统 PATH')
    process.exit(1)
  }
}

// 4. 确保目标目录存在
async function ensureDirExists(dir) {
  if (!existsSync(dir)) {
    await fs.mkdir(dir, { recursive: true })
    console.log(`✅ 创建目录：${dir}`)
  }
}

// 5. 带重试机制的操作封装
async function withRetry(operation, maxRetries = 3, delayMs = 2000) {
  let retries = 0
  while (retries < maxRetries) {
    try {
      return await operation()
    } catch (err) {
      retries++
      if (retries >= maxRetries) throw err
      console.log(`⚠️ 操作失败，将在 ${delayMs / 1000}s 后重试（${retries}/${maxRetries}）`)
      await new Promise((resolve) => setTimeout(resolve, delayMs))
    }
  }
}

// 6. 拉取单个仓库
async function pullSingleRepo(repo) {
  const {
    url,
    dir: relativeDir,
    shallow = true,
    branch = 'master',
    sparsePaths,
    maxRetries = 3,
    retryDelay = 2000
  } = repo

  const targetDir = path.resolve(process.cwd(), relativeDir)

  console.log(`\n📦 处理仓库：${url}`)
  console.log(`📂 目标路径：${targetDir}`)

  try {
    await ensureDirExists(targetDir)

    // 配置 git 实例，启用进度输出
    const git = simpleGit({
      baseDir: targetDir,
      progress: ({ method, stage, progress }) => {
        if (progress) {
          console.log(`  进度: ${method} ${stage} ${progress}%`)
        }
      }
    })

    // 检查是否已存在仓库
    const isRepo = await git.checkIsRepo()

    if (isRepo) {
      // 已有仓库：更新
      console.log('🔄 正在更新仓库...')

      // 只在已有仓库中设置本地配置
      await withRetry(
        async () => {
          // 大文件网络配置优化（仅在仓库中设置）
          await git.addConfig('http.postBuffer', httpBuffer.toString(), false, 'local')
          await git.addConfig('https.postBuffer', httpBuffer.toString(), false, 'local')
          await git.addConfig('http.timeout', timeout.toString(), false, 'local')
          await git.addConfig('https.timeout', timeout.toString(), false, 'local')

          await git.pull('origin', branch)
          console.log('✅ 仓库更新成功')
            // await injectQiankun(targetDir);
        },
        maxRetries,
        retryDelay
      )
    } else {
      // 新仓库：克隆
      console.log(`🚀 正在克隆仓库（分支：${branch}）...`)

      if (sparsePaths && sparsePaths.length > 0) {
        // 稀疏检出
        await git.init()
        await git.remote('add', 'origin', url)

        // 使用全局配置而不是本地配置
        await git.addConfig('core.sparseCheckout', 'true', true, 'global')

        const sparseFile = path.join(targetDir, '.git', 'info', 'sparse-checkout')
        await fs.writeFile(sparseFile, sparsePaths.join('\n') + '\n')

        const cloneOptions = shallow ? ['--depth=1'] : []
        await withRetry(
          async () => {
            await git.pull('origin', branch, cloneOptions)
            console.log('✅ 仓库克隆成功（稀疏检出）')
          },
          maxRetries,
          retryDelay
        )
      } else {
        // 完整克隆/浅克隆
        const cloneOptions = {
          '--branch': branch,
          '--depth': shallow ? 1 : undefined,
          '--config': `http.postBuffer=${httpBuffer}`,
          '--config': `https.postBuffer=${httpBuffer}`,
          '--config': `http.timeout=${timeout}`,
          '--config': `https.timeout=${timeout}`
        }
        await withRetry(
          async () => {
            await git.clone(url, targetDir, cloneOptions)
            //  await injectQiankun(targetDir);
            console.log('✅ 仓库克隆成功')
          },
          maxRetries,
          retryDelay
        )
      }
    }
  } catch (err) {
    console.error(`❌ 处理失败：${err.message}`)
  }
}

// 7. 批量拉取所有仓库
async function pullAllRepos() {
  try {
    await checkGitInstalled()
    const repos = await readConfig()

    if (repos.length === 0) {
      console.log('ℹ️ 配置文件中没有需要拉取的仓库')
      return
    }

    // 控制并发数（同时处理2个仓库）
    const concurrency = 2
    for (let i = 0; i < repos.length; i += concurrency) {
      const batch = repos.slice(i, i + concurrency)
      await Promise.all(batch.map((repo) => pullSingleRepo(repo)))
    }

    console.log('\n🎉 所有仓库处理完成')
  } catch (err) {
    console.error(`💥 执行失败：${err.message}`)
    process.exit(1)
  }
}

// 执行主逻辑
pullAllRepos()
